package com.xinzhidi.web.sim.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xinzhidi.common.core.domain.model.LoginUser;
import com.xinzhidi.common.core.page.TableDataInfo;
import com.xinzhidi.common.exception.ServiceException;
import com.xinzhidi.common.utils.DateUtils;
import com.xinzhidi.common.utils.SecurityUtils;
import com.xinzhidi.common.utils.StringUtils;
import com.xinzhidi.common.utils.bean.BeanUtils;
import com.xinzhidi.common.utils.poi.CellData;
import com.xinzhidi.common.utils.poi.ExcelData;
import com.xinzhidi.common.utils.poi.ReadExcelUtil;
import com.xinzhidi.web.equipment.domain.Equipment;
import com.xinzhidi.web.equipment.service.EquipmentService;
import com.xinzhidi.web.sim.domain.SimCard;
import com.xinzhidi.web.sim.domain.dto.SimCardAddDto;
import com.xinzhidi.web.sim.domain.dto.SimCardListDto;
import com.xinzhidi.web.sim.domain.dto.SimCardUpdDto;
import com.xinzhidi.web.sim.domain.vo.SimCardInfoVo;
import com.xinzhidi.web.sim.domain.vo.SimCardListVo;
import com.xinzhidi.web.sim.mapper.SimCardMapper;
import com.xinzhidi.web.sim.service.ISimCardService;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.util.*;
import java.util.stream.Collectors;


/**
 * sim卡Service业务层处理
 *
 * @author ruoyi
 * @date 2023-05-25
 */
@Service
public class SimCardServiceImpl extends ServiceImpl<SimCardMapper, SimCard> implements ISimCardService {
    @Autowired
    private SimCardMapper simCardMapper;

    @Autowired
    private EquipmentService equipmentService;

    /**
     * 查询sim卡
     *
     * @param id sim卡主键
     * @return sim卡
     */
    @Override
    public SimCardInfoVo selectSimCardById(Long id) {
        SimCard simCard = simCardMapper.selectById(id);
        SimCardInfoVo infoVo = new SimCardInfoVo();
        BeanUtils.copyProperties(simCard, infoVo);
        return infoVo;
    }

    /**
     * 查询sim卡列表
     *
     * @param dto 查询sim卡dto
     * @return sim卡
     */
    @Override
    public TableDataInfo<SimCardListVo> selectSimCardList(SimCardListDto dto) {
        LambdaQueryWrapper<SimCard> wrapper = Wrappers.lambdaQuery();
        wrapper.like(StringUtils.isNotEmpty(dto.getAddress()), SimCard::getAddress, dto.getAddress());
        wrapper.like(StringUtils.isNotEmpty(dto.getEquipmentCode()), SimCard::getEquipmentCode, dto.getEquipmentCode());
        wrapper.orderByDesc(SimCard::getId);
        return TableDataInfo.getDataTable(simCardMapper.selectList(wrapper), (domain -> {
            SimCardListVo vo = new SimCardListVo();
            BeanUtils.copyProperties(domain, vo);
            return vo;
        }));
    }

    /**
     * 新增sim卡
     *
     * @param dto 新增sim卡dto
     * @return 结果
     */
    @Override
    public int insertSimCard(SimCardAddDto dto) {
        checkExist(null, dto.getAddress(), dto.getEquipmentCode());
        LoginUser loginUser = SecurityUtils.getLoginUser();

        SimCard simCard = new SimCard();
        BeanUtils.copyProperties(dto, simCard);
        simCard.setCreateBy(loginUser.getUserId().toString());
        simCard.setCreateTime(DateUtils.getNowDate());
        return simCardMapper.insert(simCard);
    }

    /**
     * 修改sim卡
     *
     * @param dto 修改sim卡dto
     * @return 结果
     */
    @Override
    public int updateSimCard(SimCardUpdDto dto) {
        checkExist(dto.getId(), dto.getAddress(), dto.getEquipmentCode());
        LoginUser loginUser = SecurityUtils.getLoginUser();
        SimCard simCard = new SimCard();
        BeanUtils.copyProperties(dto, simCard);
        simCard.setUpdateBy(loginUser.getUserId().toString());
        simCard.setUpdateTime(DateUtils.getNowDate());
        return simCardMapper.updateById(simCard);
    }

    public void checkExist(Long id, String address, String equipmentCode) {
        LambdaQueryWrapper<SimCard> cardLambdaQueryWrapper = Wrappers.lambdaQuery();
        cardLambdaQueryWrapper.ne(id != null, SimCard::getId, id)
                .and(wrapper -> {
                    wrapper.eq(SimCard::getAddress, address);
                    wrapper.or().eq(SimCard::getEquipmentCode, equipmentCode);
                });

        if (simCardMapper.selectCount(cardLambdaQueryWrapper) > 0) {
            throw new ServiceException("设备地址或设备编号已存在！");
        }
    }

    /**
     * 批量删除sim卡
     *
     * @param ids 需要删除的sim卡主键
     * @return 结果
     */
    @Override
    public int deleteSimCardByIds(Long[] ids) {
        return simCardMapper.deleteBatchIds(Arrays.asList(ids));
    }

    /**
     * 删除sim卡信息
     *
     * @param id sim卡主键
     * @return 结果
     */
    @Override
    public int deleteSimCardById(Long id) {
        return simCardMapper.deleteById(id);
    }

    @Override
    public String importExcel(MultipartFile file) {
        LoginUser loginUser = SecurityUtils.getLoginUser();
        List<SimCard> entityList = parseExcelFile(file);
        if (CollectionUtils.isNotEmpty(entityList)) {
            List<SimCard> list = new ArrayList<>();
            SimCard simCard;
            LambdaQueryWrapper<SimCard> entityLambdaQueryWrapper;
            for (SimCard card : entityList) {
                entityLambdaQueryWrapper = new LambdaQueryWrapper<>();
                entityLambdaQueryWrapper.and((wrapper) -> {
                    wrapper.eq(SimCard::getAddress, card.getAddress())
                            .or().eq(SimCard::getEquipmentCode, card.getEquipmentCode());
                });
                simCard = this.getOne(entityLambdaQueryWrapper);
                if (simCard != null) {
                    simCard.setAddress(card.getAddress());
                    simCard.setEquipmentCode(card.getEquipmentCode());
                    simCard.setUpdateTime(new Date());
                    simCard.setUpdateBy(loginUser.getUserId().toString());
                    list.add(simCard);
                } else {
                    card.setCreateBy(loginUser.getUserId().toString());
                    list.add(card);
                }
            }
            this.saveOrUpdateBatch(list);
        }
        return "导入成功";
    }

    private List<SimCard> parseExcelFile(MultipartFile file) {
        ExcelData excelData;
        try {
            excelData = ReadExcelUtil.readTable(file.getInputStream(), file.getOriginalFilename());
        } catch (Exception e) {
            throw new RuntimeException("Excel Parse Failed.");
        }
        List<SimCard> list = new ArrayList<>();
        if (excelData.getRow() == 0) {
            return list;
        }
        for (Map.Entry<String, List<CellData>> entry : excelData.getData().entrySet()) {
            List<CellData> cellDataList = entry.getValue();
            SimCard entity = new SimCard();
            for (CellData cellData : cellDataList) {
                String value = cellData.getValue();
                if (value.contains(".0")) {
                    value = value.replace(".0", "");
                }
                if (StringUtils.isNotBlank(value)) {
                    if (cellData.getColName().equalsIgnoreCase("地址域")) {
                        entity.setAddress(value);
                    }
                    if (cellData.getColName().equalsIgnoreCase("设备编码")) {
                        entity.setEquipmentCode(value);
                    }
                }

            }
            list.add(entity);
        }
        Map<Object, Long> collect2 = list.stream().collect(
                Collectors.groupingBy(SimCard::getAddress, Collectors.counting()));

        if (collect2 != null) {
            List<Object> collect3 = collect2.keySet().stream().
                    filter(key -> collect2.get(key) > 1).collect(Collectors.toList());
            if (CollectionUtils.isNotEmpty(collect3)) {
                throw new ServiceException("地址域【" + StringUtils.join(collect3) + "】重复");
            }

        }

        Map<Object, Long> collect4 = list.stream().collect(
                Collectors.groupingBy(SimCard::getEquipmentCode, Collectors.counting()));


        if (collect4 != null) {
            List<Object> collect5 = collect4.keySet().stream().
                    filter(key -> collect4.get(key) > 1).collect(Collectors.toList());
            if (CollectionUtils.isNotEmpty(collect5)) {
                throw new ServiceException("设备编码" + StringUtils.join(collect5) + "重复!");
            }
        }
        return list;
    }

    /**
     * 校验设备地址是否存在
     *
     * @param dtuId   dtuId
     * @param address 设备地址域
     * @return true：存在 false：不存在
     */
    @Override
    public boolean checkSimCard(long dtuId, String address) {
        //1：根据dtuId和address查询设备
        //2：通过设备编码查找sim卡
        LambdaQueryWrapper<Equipment> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(Equipment::getDtuId, dtuId)
                .eq(Equipment::getAddress, address);
        Equipment equipment = equipmentService.getOne(wrapper);
        if (equipment == null) {
            return false;
        }
        LambdaQueryWrapper<SimCard> simCardLambdaQueryWrapper = Wrappers.lambdaQuery();
        simCardLambdaQueryWrapper.eq(SimCard::getEquipmentCode, equipment.getEquipmentCode());
        SimCard simCard = this.getOne(simCardLambdaQueryWrapper);
        if (simCard == null) {
            return false;
        }
        return true;
    }

}
